import tkinter as tk
from tkinter import ttk
import markdown
from tkhtmlview import HTMLLabel
from client import MCPClient
import asyncio
import threading
from queue import Queue

class Text2SqlUI:
    def __init__(self, root):
        self.root = root
        self.root.title("Text2Sql智能体")
        self.root.geometry("800x400")
        
        # 设置整体样式
        self.style = ttk.Style()
        self.style.configure('TFrame', background='#f0f0f0')
        self.style.configure('TLabel', background='#f0f0f0', font=('Microsoft YaHei UI', 10))
        self.style.configure('TButton', font=('Microsoft YaHei UI', 9))  # 只设置字体
        
        # 创建主框架
        self.main_frame = ttk.Frame(self.root, padding="20", style='TFrame')
        self.main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 创建输入区域
        self.create_input_area()
        
        # 创建结果显示区域
        self.create_result_area()
        
        # 创建进度条和状态区域
        self.create_status_area()
        
        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        self.main_frame.columnconfigure(1, weight=1)
        self.main_frame.rowconfigure(2, weight=1)  # 让结果区域可以扩展
        
        # 初始化异步相关的变量
        self.client: MCPClient=None
        self.loop = None
        self.client_ready = threading.Event()
        self.result_queue = Queue()
        
        # 启动异步事件循环线程
        self.start_async_loop()
        
    def start_async_loop(self):
        """启动异步事件循环线程"""
        def run_async_loop():
            self.loop = asyncio.new_event_loop()
            asyncio.set_event_loop(self.loop)
            
            async def init_client():
                self.client = await MCPClient()
                self.client_ready.set()
                self.update_status("MCP客户端初始化完成")
                
            self.loop.run_until_complete(init_client())
            self.loop.run_forever()
            
        self.async_thread = threading.Thread(target=run_async_loop, daemon=True)
        self.async_thread.start()
        
    def create_input_area(self):
        """创建输入区域：文本框和执行按钮"""
        # 输入区域容器
        input_frame = ttk.Frame(self.main_frame, style='TFrame')
        input_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # 输入框标签
        input_label = ttk.Label(input_frame, text="请输入您的需求:", style='TLabel')
        input_label.grid(row=0, column=0, sticky=tk.W, pady=(0, 5))
        
        # 创建输入框和按钮的容器
        input_container = ttk.Frame(input_frame, style='TFrame')
        input_container.grid(row=1, column=0, sticky=(tk.W, tk.E))
        input_container.columnconfigure(0, weight=1)
        
        # 文本输入框
        self.text_input = ttk.Entry(
            input_container,
            width=70,
            font=('Microsoft YaHei UI', 10)
        )
        self.text_input.grid(row=0, column=0, sticky=(tk.W, tk.E))
        
        # 执行按钮 - 使用默认样式
        self.execute_btn = ttk.Button(
            input_container, 
            text="执行",
            command=self.execute_query,
            width=10
        )
        self.execute_btn.grid(row=0, column=1, sticky=tk.W, padx=(10, 0))
        
    def create_result_area(self):
        """创建结果显示区域"""
        # 结果区域标签
        result_label = ttk.Label(self.main_frame, text="操作结果:", style='TLabel')
        result_label.grid(row=1, column=0, columnspan=2, sticky=tk.W, pady=(10, 5))
        
        # 结果显示区域容器
        result_frame = ttk.Frame(self.main_frame, style='TFrame')
        result_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S))
        result_frame.columnconfigure(0, weight=1)
        result_frame.rowconfigure(0, weight=1)
        
        # 使用HTMLLabel显示markdown格式的结果，文字颜色设为灰色
        self.result_display = HTMLLabel(
            result_frame,
            html="<div style='font-family: Microsoft YaHei UI; padding: 10px; color: #666666;'>结果将在这里显示...</div>",
            background='white',
            relief='solid'
        )
        self.result_display.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
    def create_status_area(self):
        """创建状态区域"""
        # 状态区域容器
        status_frame = ttk.Frame(self.main_frame, style='TFrame')
        status_frame.grid(row=3, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(10, 0))
        
        # 进度条
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(
            status_frame,
            length=300,
            mode='indeterminate',
            variable=self.progress_var
        )
        self.progress_bar.grid(row=0, column=0, sticky=(tk.W, tk.E))
        
        # 状态标签
        self.status_label = ttk.Label(
            status_frame, 
            text="MCP客户端初始化中...", 
            style='TLabel'
        )
        self.status_label.grid(row=1, column=0, sticky=tk.W, pady=(5, 0))
        
        # 初始状态隐藏进度条
        self.progress_bar.grid_remove()
        
    def update_status(self, message):
        """更新状态信息"""
        self.root.after(0, lambda: self.status_label.configure(text=message))
        
    def execute_query(self):
        """执行查询"""
        if not self.client_ready.is_set():
            self.result_display.set_html(
                "<div style='color: red; font-family: Microsoft YaHei UI; padding: 10px; font-weight: normal;'>"
                "客户端尚未初始化完成，请稍后重试</div>"
            )
            return
            
        # 获取输入文本
        query_text = self.text_input.get().strip()
        if not query_text:
            return
            
        # 清除上次的结果
        self.result_display.set_html(
            "<div style='font-family: Microsoft YaHei UI; padding: 10px; color: #666666;'>正在查询中...</div>"
        )
            
        # 显示进度条并开始动画
        self.progress_bar.grid()
        self.progress_bar.start()
        self.execute_btn.state(['disabled'])  # 禁用按钮
        self.update_status("正在操作中...")
        
        async def async_execute():
            try:
                result = await self.client.execute(query_text)
                # 直接在主线程中更新UI
                self.root.after(0, lambda: self.handle_result("success", result))
            except Exception as e:
                # 直接在主线程中更新UI
                self.root.after(0, lambda: self.handle_result("error", str(e)))
                
        # 将任务提交到事件循环
        asyncio.run_coroutine_threadsafe(async_execute(), self.loop)
        
    def handle_result(self, result_type, result):
        """在主线程中处理结果"""
        if result_type == "success":
            html_content = markdown.markdown(result)
            self.result_display.set_html(
                f"<div style='font-family: Microsoft YaHei UI; padding: 10px; color: #666666;'>{html_content}</div>"
            )
            self.update_status("操作完成")
        else:
            self.result_display.set_html(
                "<div style='color: red; font-family: Microsoft YaHei UI; padding: 10px; font-weight: normal;'>"
                f"执行出错：{result}</div>"
            )
            self.update_status("查询出错")
            
        self.finish_query()
        
    def check_result(self):
        """检查异步操作的结果"""
        try:
            result_type, result = self.result_queue.get_nowait()
            
            if result_type == "success":
                html_content = markdown.markdown(result)
                self.result_display.set_html(
                    f"<div style='font-family: Microsoft YaHei UI; padding: 10px;'>{html_content}</div>"
                )
                self.update_status("查询完成")
            else:
                self.result_display.set_html(
                    "<div style='color: red; font-family: Microsoft YaHei UI; padding: 10px;'>"
                    f"执行出错：{result}</div>"
                )
                self.update_status("查询出错")
                
            self.finish_query()
        except Queue.Empty:
            # 如果队列为空，继续等待
            self.root.after(100, self.check_result)
            
    def finish_query(self):
        """完成查询后的清理工作"""
        self.progress_bar.stop()
        self.progress_bar.grid_remove()
        self.execute_btn.state(['!disabled'])
        
    def on_closing(self):
        """窗口关闭时的清理工作"""
        if self.loop:
            self.loop.call_soon_threadsafe(self.loop.stop)
        self.root.destroy()

def main():
    root = tk.Tk()
    # 设置窗口图标
    try:
        root.iconbitmap('favicon.ico')  # 如果有图标文件的话
    except:
        pass
    app = Text2SqlUI(root)
    root.protocol("WM_DELETE_WINDOW", app.on_closing)  # 设置窗口关闭处理
    root.mainloop()

if __name__ == "__main__":
    main()
